﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZGRemote.Client.Common;
using ZGRemote.Common.Message;
using ZGRemote.Common.Message.RemoteShell;
using ZGRemote.Common.Processor;
using static System.Net.Mime.MediaTypeNames;

namespace ZGRemote.Client.Handler
{
    [CanProcessMessage(typeof(CreateShell),
                       typeof(CloseShell),
                       typeof(DoCommand))]
    public class RemoteShellHandler : HandlerBase<RemoteShellHandler>
    {
        private Shell shell;

        public override void Excute(MessageBase message)
        {
            switch(message)
            {
                case CreateShell createShell:
                    CreateShell(createShell);
                    break;
                case CloseShell closeShell:
                    CloseShell(closeShell);
                    break;
                case DoCommand doCommand:
                    DoCommand(doCommand);
                    break;
            }
        }

        private void CreateShell(CreateShell message)
        {
            CreateShellResponse response = new CreateShellResponse();
            response.ID = message.ID;

            try
            {
                if (shell != null)
                {
                    shell.OutputError -= OutputError;
                    shell.OutputText -= OutputText;
                    shell.Dispose();
                }
                shell = new Shell();
                shell.OutputError += OutputError;
                shell.OutputText += OutputText;
                shell.Start();
                response.Success = true;
            }
            catch (Exception ex)
            {
                response.Success = false;
                response.Message = ex.Message;
            }
            SendMessage(UserContext, response);
        }

        private void CloseShell(CloseShell message)
        {
            if (shell != null)
            {
                shell.OutputError -= OutputError;
                shell.OutputText -= OutputText;
                shell.Dispose();
            }
            shell = null;
        }

        private void DoCommand(DoCommand message)
        {
            if(shell != null && shell.IsRunning)
            {
                shell.RunCmd(message.Command);
            }
        }

        private void OutputText(string text) 
        {
            DoCommandResponse message = new DoCommandResponse();
            message.ResponseType = DoCommandResponseType.Message;
            message.Message = text;
            SendMessage(UserContext, message);
        }

        private void OutputError(string error) 
        {
            DoCommandResponse message = new DoCommandResponse();
            message.ResponseType = DoCommandResponseType.Error;
            message.Message = error;
            SendMessage(UserContext, message);
        }
    }
}
